package br.uff.mic1.model;


public class Cache {

	public static final int NUMERO_SLOTS = 16;
	
	//fazer generico
	private final static int TAG_INICIO = 0;
	private final static int TAG_FIM = 6;
	private final static int SLOT_INICIO = 6;
	private final static int SLOT_FIM = 10;
	private final static int PALAVRA_INICIO = 10;
	private final static int PALAVRA_FIM = 12;
	
	private Slot[] slots = new Slot[Cache.NUMERO_SLOTS];
	
	public Cache()
	{
		for (int i=0; i < Cache.NUMERO_SLOTS; i++)
			this.slots[i] = new Slot();
	}
	
	//TODO: ver como funciona o bit de validacao!!!
	//nao esta verificando isso
	public String getPalavra(String enderecoMemoriaPrincipal)
	{
		
		//se estiver na cache
		String tag = enderecoMemoriaPrincipal.substring(Cache.TAG_INICIO, Cache.TAG_FIM);
		String slot = enderecoMemoriaPrincipal.substring(Cache.SLOT_INICIO, Cache.SLOT_FIM);
 		int indiceSlot = Integer.parseInt(slot, 2);
		
		if (this.slots[indiceSlot].getTag().equals(tag))
		{
			String strIndexPalavra = enderecoMemoriaPrincipal.substring(Cache.PALAVRA_INICIO, Cache.PALAVRA_FIM);
			int indicePalavra = Integer.parseInt(strIndexPalavra, 2);
			return this.slots[indiceSlot].getPalavra(indicePalavra);
		}
		return "";
	}
	
	public int setPalavra(String enderecoMemoriaPrincipal, String conteudo)
	{
		//se estiver na cache
		String tag = enderecoMemoriaPrincipal.substring(Cache.TAG_INICIO, Cache.TAG_FIM);
		int indiceSlot = Integer.parseInt(enderecoMemoriaPrincipal.substring(Cache.SLOT_INICIO, Cache.SLOT_FIM), 2);
		
		if (this.slots[indiceSlot].getTag().equals(tag))
		{
			int indicePalavra = Integer.parseInt(enderecoMemoriaPrincipal.substring(Cache.PALAVRA_INICIO, Cache.PALAVRA_FIM), 2);
			this.slots[indiceSlot].setPalavra(indicePalavra, conteudo);
			this.slots[indiceSlot].setValidacao("1");
			return indiceSlot;
		}
		return -1;
	}
	
	public MemoriaPrincipal setSlot(MemoriaPrincipal mp, String enderecoMemoriaPrincipal)
	{
		int index = Integer.parseInt(enderecoMemoriaPrincipal,2);
		String[] bloco = mp.getBloco(index);
		String tag = enderecoMemoriaPrincipal.substring(Cache.TAG_INICIO, Cache.TAG_FIM);
		int indiceSlot = Integer.parseInt(enderecoMemoriaPrincipal.substring(Cache.SLOT_INICIO, Cache.SLOT_FIM), 2);
		
		if ("1".equals(this.slots[indiceSlot].getValidacao()))
		{
			String strIndex2 = this.slots[indiceSlot].getTag();
			strIndex2 = strIndex2 + Integer.toBinaryString(indiceSlot) + "00";
			mp.setBloco(strIndex2, this.slots[indiceSlot].getBloco());
		}
		
		this.slots[indiceSlot].setBloco(bloco);
		this.slots[indiceSlot].setTag(tag);
		
		return mp;
	}
	
	public String[] getBloco(int indexSlot)
	{
		if (indexSlot > Cache.NUMERO_SLOTS || indexSlot < 0)
			throw new IllegalArgumentException("Slot inexistente");
		
		if (null != this.slots[indexSlot])
			return this.slots[indexSlot].getBloco();
		return null;
	}
	
	
	
}
